el-table-column
<template>
  <div>
    <div class="row mb-1">
      <Adduser
        ref="adduserview"
        :group="group"
        :ID="selectedUid"
        :selected-user="selectedUser"
        :create="create"
        :teamid="ID"
        :start="start"
        :close="() => (selectedUid = 0)"
      >
      </Adduser>
      <el-button
        v-if="!tenant_id"
        :disabled="disabled"
        style="width: 120px"
        @click="setCourse"
        type="primary"
        size="default"
        >设置课程</el-button
      >
      <el-select
        v-model="teamusergroupid"
        clearable
        placeholder="请选择团队组"
        style="width: 220px"
      >
        <el-option
          v-for="item in selectGroup"
          :key="item.name"
          :label="item.name"
          :value="item.ID!"
        >
        </el-option>
      </el-select>
      <el-button @click="teamUserExport" type="primary" style="width: 100px"
        >导出Excel</el-button
      >
      <div class="col">
        <el-input v-model="like" placeholder="请输入内容" clearable>
          <template #append>
            <el-button @click="start">
              搜索&nbsp;
              <el-icon>
                <Search />
              </el-icon>
            </el-button>
          </template>
        </el-input>
      </div>
    </div>
    <div class="row mb-1">
      <div class="col">
        <el-table
          :data="tableData"
          @selection-change="handleSelectionChange"
          height="68vh"
          v-loading="loading"
          style="width: 100%"
        >
          <el-table-column type="selection" width="55" />
          <!-- <el-table-column sortable type="index" width="60"></el-table-column> -->
          <el-table-column
            sortable
            prop="userid"
            label="用户ID"
            width="110"
          ></el-table-column>
          <el-table-column
            sortable
            prop="username"
            label="用户"
            :formatter="({ user }) => user.name"
          ></el-table-column>
          <el-table-column
            prop="user.phonenum"
            label="手机号"
          ></el-table-column>
          <el-table-column
            sortable
            prop="userid"
            label="状态"
            width="100"
            :formatter="({ jurisdiction }) => st[jurisdiction]"
          >
          </el-table-column>
          <el-table-column
            sortable
            prop="isAdmin"
            label="类型"
            width="100"
            :formatter="
              ({ isAdmin }) => {
                return admin[isAdmin];
              }
            "
          ></el-table-column>
          <el-table-column
            sortable
            :formatter="
              ({ teamusergroupid }) => formatGroupName(teamusergroupid)
            "
            label="团队组"
          >
          </el-table-column>
          <el-table-column
            prop="createdAt"
            sortable="custom"
            :formatter="({ createdAt }) => formatter(createdAt)"
            label="加入时间"
          >
          </el-table-column>
          <el-table-column label="操作" width="230">
            <template #default="scope">
              <el-button @click="change(scope.row.ID)" type="warning"
                >修改</el-button
              >
              <el-button type="danger" @click="delteamuser(scope.row.ID)"
                >删除</el-button
              >
            </template>
          </el-table-column>
        </el-table>
      </div>
    </div>
    <el-pagination
      class="pager"
      size="default"
      :page-size="limit"
      :page-sizes="pageSizes"
      :total="totalCount"
      layout="total, sizes, prev, pager, next"
      @current-change="changePage"
      @size-change="handleSizeChange"
      :current-page="Math.floor(offset / limit) + 1"
    >
    </el-pagination>

    <!-- 弹窗 课程包配置 -->
    <el-dialog
      class="catebag-cfg-container"
      title="课程配置"
      v-model="courseCfgDialogVisible"
      min-width="80vw"
      width="80vw"
      :before-close="close"
      top="0"
    >
      <template #header>
        <span class="icon-text el-dialog__header-title">
          <el-icon class="text-primary">
            <Guide />
          </el-icon>
          课程配置
        </span>
      </template>
      <div class="container-box">
        <el-form label-position="top" label-width="210px" size="default">
          <el-form-item label="成员">
            <el-scrollbar>
              <div class="container-header">
                <el-text
                  siez="default"
                  type="primary"
                  v-for="(v, k) in multipleSelection"
                  :key="k"
                >
                  {{ v.user?.name
                  }}{{ k == multipleSelection.length - 1 ? "" : "、" }}
                </el-text>
              </div>
            </el-scrollbar>
          </el-form-item>
        </el-form>
        <div class="container-content">
          <div>
            <el-form label-position="top" label-width="210px" size="default">
              <el-form-item label="配置团队成员可见课程:">
                <el-scrollbar>
                  <el-checkbox-group
                    class="catebag-list"
                    v-model="checkedCatebags"
                    size="default"
                  >
                    <div
                      class="form-item"
                      v-for="(v, k) in groupedByCatebagArr"
                      :key="k"
                      @mouseenter="showCourseList(v)"
                    >
                      <el-checkbox class="form-item-check-box" :value="v.cID">{{
                        v.name
                      }}</el-checkbox>
                      <div class="desc cursor-pointer">
                        <span>{{ v.info }}</span>
                      </div>
                      <!-- <div class="btn-box">
                            <el-button type='primary' link @click="showCourse(v.ID)">查看课程</el-button>
                          </div> -->
                    </div>
                  </el-checkbox-group>
                </el-scrollbar>
              </el-form-item>
              <el-form-item> </el-form-item>
            </el-form>
            <el-button
              class="save-btn"
              type="primary"
              size="default"
              @click="submitUpdateUserCourseGroup"
              >保存</el-button
            >
          </div>
          <div class="container-right">
            <el-table
              class="container-right-table"
              width="100%"
              stripe
              :data="courseList"
            >
              <template v-slot:empty>
                <el-empty
                  image="https://cdn-hterobot.oss-cn-qingdao.aliyuncs.com/image/ojSass-empty.png"
                />
              </template>
              <!-- <el-table-column type="index" width="50" /> -->
              <el-table-column prop="name" label="课程名" width="">
                <template #header>
                  {{ selectedCateBagName }}({{ courseList.length }})
                </template>
                <template #default="{ row }">
                  {{ row.name }}
                </template>
              </el-table-column>
            </el-table>
          </div>
        </div>
      </div>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { Guide, Search } from "@element-plus/icons-vue";
import { ElMessage, ElMessageBox } from "element-plus";
import { computed, inject, onMounted, ref, watch } from "vue";
import {
  asyncAdminAddUsercourse,
  asyncSelectPackageCatebagRelation,
  asyncadmindelteamuser,
  asyncselectUsercourse,
  asyncselectteamcoursegroup,
  asyncselectteamuser,
} from "../../../api/index";
import Alymodel from "../../../mysql_interface/model";
import {
  default as Studycodemodel,
  default as study,
} from "../../../mysql_interface/studycodemodel";
import { courseCatebag } from "../../../sassMgmt/views/data/data";
import { getGroupedByCatebagArr } from "../../../util/cloudClass";
import { getExceltodownload } from "../../../util/excel";
import { toLocaleDateString } from "../../../util/time";
import Adduser from "./adduserteam.vue";

const defaultPIDs = courseCatebag.map((e) => e.pID);

// 码客行
const tenant_id = inject<string | undefined>("tenant_id", undefined);

const p = defineProps<{
  ID: number;
  team: Studycodemodel.Iteam;
  group: Studycodemodel.Iteamusergroup[];
}>();
const st: Record<any, any> = {
  "0": "成员",
  "1": "用户申请中",
  "2": "管理员邀请中",
  "3": "拒绝加入",
};
const admin: Record<any, any> = {
  "0": "团员",
  "1": "管理员",
  "2": "教师",
};

const defaultTeamUser: Studycodemodel.Iteamuser = {
  isAdmin: 0,
  teamusergroupid: undefined,
  username: "",
  user: {},
};
const selectedUid = ref(0);
const ID = computed<number>(() => {
  return Number(p.ID);
});
watch(
  () => ID,
  () => {
    start();
  }
);

const adduserview = ref();
const selectedUser = computed(() => {
  return (
    tableData.value.find((v) => v.ID == selectedUid.value) || defaultTeamUser
  );
});
function create() {
  selectedUid.value = 0;
}

onMounted(() => {
  start();
});

const selectGroup = computed(() => {
  return [
    { ID: "全部", name: "全部" },
    { ID: "未分组", name: "未分组" },
    ...p.group,
  ];
});
const loading = ref(false);
const limit = ref(20);
const offset = ref(0);
const pageSizes: number[] = [limit.value, 50, 100, 200, 400, 500, 1000, 2000];
const totalCount = ref(0);
const like = ref("");
const teamusergroupid = ref();
const tableData = ref<study.Iteamuser[]>([]);
async function start() {
  loading.value = true;
  if (ID.value) {
    if (like.value) {
    }
    // 获取团队成员
    let cond = {
      teamid: ID.value,
      _limit: limit.value,
      _offset: offset.value,
      _like: like.value ? ["username", like.value] : undefined,
    };
    let groupId =
      teamusergroupid.value === "未分组" ? null : teamusergroupid.value;
    if (groupId !== "全部") {
      cond.teamusergroupid = groupId;
    }
    const { rows, count } = await asyncselectteamuser(cond);
    tableData.value = rows;
    totalCount.value = count;

    // 获取团队代理商课包
    const ret = await asyncselectteamcoursegroup({ teamid: ID.value });
    // 没有查到就用前端默认的7个代理商课包
    const pIds = ret.rows?.length
      ? ret.rows.map((e) => Number(e.coursegroupid))
      : defaultPIDs;
    // 代理商课包-课程组
    await getPackageCatebagRelation(pIds);
  } else {
    ElMessage.error("没有此团队");
  }
  loading.value = false;
}

// op
function change(ID: number) {
  if (adduserview.value) {
    adduserview.value.setdialogVisible(true);
    selectedUid.value = ID;
  }
}
async function delteamuser(ID: number) {
  ElMessageBox.confirm("是否删除此团员？", "警告", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning",
  })
    .then(() => {
      asyncadmindelteamuser({ ID })
        .then(() => {
          ElMessage.success("删除成功");
          start();
        })
        .catch((e) => {
          ElMessage.error("删除失败" + e);
        });
    })
    .catch(() => {});
}
// formatter
function formatGroupName(teamusergroupid?: number) {
  const d = p.group?.find((v: study.Iteamusergroup) => v.ID == teamusergroupid);
  return d ? d.name : "未分组";
}
function formatter(updatedAt: string | number | Date) {
  return toLocaleDateString(updatedAt);
}
function changePage(val: number) {
  offset.value = limit.value * (val - 1);
  start();
}
const handleSizeChange = (val: number) => {
  limit.value = val;
  start();
};

// 课程相关

// 根据课程获取课程包
function formatUserCourseCatebag(row: Studycodemodel.Iteamuser) {
  let intableCateBagName: string[] = [];
  let userId = row.userid;
  matchCourseCateBag(userId, (catebag: Alymodel.IMcatebag) => {
    intableCateBagName.push(catebag.name || "");
  });
  return intableCateBagName;
}

const checkedCatebags = ref<any[]>([]);
// 弹窗复选框成员课程包回填
async function formatterCourseGroupCheckbox() {
  if (multipleSelection.value?.length === 1) {
    const selectedUid = multipleSelection.value[0].userid;
    await getUsercourse([selectedUid]);
    matchCourseCateBag(selectedUid, (catebag: Alymodel.IMcatebag) => {
      checkedCatebags.value.push(catebag.ID);
    });
  }
}
// 利用课程和课包-课程得出课程组名字
function matchCourseCateBag(
  uid: number,
  fn: (catebag: Alymodel.IMcatebag) => void
) {
  let userCourse = userCourseMap.value[uid] || [];
  let catebagMap = new Map<number, Alymodel.IMcatebag>();
  // 所有userCourseID
  const userCourseSet = new Set(userCourse.map((uc) => uc.course_ID));
  for (const catebag of groupedByCatebagArr.value) {
    const packages = catebag.packages || [];
    for (const pkg of packages) {
      if (userCourseSet.has(pkg.course_ID)) {
        if (!catebagMap.has(catebag.cID)) {
          catebagMap.set(catebag.cID, catebag);
          fn(catebag);
        }
        break;
      }
    }
  }
}
// 获取成员课程配置 user_ID - course[]
const userCourseMap = ref<{ [uid: number]: Alymodel.IMusercourse[] }>({});
async function getUsercourse(uid: number[]) {
  userCourseMap.value = await asyncselectUsercourse({
    teamid: ID.value,
    user_ID: uid,
    // user_ID: tableData.value.map(e => e.userid),
    _order: "createtime",
  });
}
// 代理商课包-课程组关系
const groupedByCatebagArr = ref<Alymodel.GroupedByCatebag[]>([]);
// 获取指定代理商课包 =》 课程 =》 课程组 关系
const teamPackageCatebagRelation = ref<Alymodel.PackageCatebagRelation[]>([]);
async function getPackageCatebagRelation(pID: number[]) {
  const { rows: data, count } = await asyncSelectPackageCatebagRelation({
    ID: pID,
  });
  teamPackageCatebagRelation.value = data;
  // 按课程包分组
  groupedByCatebagArr.value = getGroupedByCatebagArr(data);
}

const courseCfgDialogVisible = ref(false);
// 设置课程
function setCourse() {
  courseCfgDialogVisible.value = true;
  showCourseList(groupedByCatebagArr.value[0]);
  // 成员课程包回填
  formatterCourseGroupCheckbox();
}
const disabled = computed(() => {
  return !multipleSelection.value.length;
});

// 多选框
const multipleSelection = ref<Studycodemodel.Iteamuser[]>([]);
function handleSelectionChange(v: Studycodemodel.Iteamuser[]) {
  multipleSelection.value = v;
}
// 保存
async function submitUpdateUserCourseGroup() {
  let uids = multipleSelection.value.map((e) => e.userid);
  // 删除
  let del_course_ID: number[] = [];
  // 新增
  let add_course_ID: number[] = [];

  groupedByCatebagArr.value.forEach((catebag) => {
    catebag.packages?.forEach((pkgItem) => {
      // 删除所有课程
      del_course_ID.push(pkgItem.course_ID as number);
      // 匹配复选框（CID）选中课程包，所有课程
      if (checkedCatebags.value.includes(catebag.cID)) {
        add_course_ID.push(pkgItem.course_ID as number);
      }
    });
  });
  let usercourse: { user_ID: number; course_ID: number; permission: number }[] =
    [];
  uids.forEach((uid) => {
    add_course_ID.forEach((cid) => {
      usercourse.push({
        user_ID: uid as number,
        course_ID: cid,
        permission: 100,
      });
    });
  });
  try {
    await asyncAdminAddUsercourse({
      teamid: ID.value,
      user_ID: uids,
      course_ID: del_course_ID,
      usercourse,
    });
    ElMessage.success("操作成功");
    close();
    start();
  } catch (e: any) {
    ElMessage.error(e);
  }
}

// hover单个课程组-课程
const selectedCateBagID = ref();
const courseList = ref<Alymodel.IMcourse[]>([]);
const selectedCateBagName = ref("");
function showCourseList(v: Alymodel.GroupedByCatebag) {
  selectedCateBagID.value = v.cID;
  selectedCateBagName.value = v.name || "";
  courseList.value = v.packages.sort(
    (a, b) => (a.course_ID || 0) - (b.course_ID || 0)
  );
}

function close() {
  courseCfgDialogVisible.value = false;
  checkedCatebags.value = [];
}

// 导出  ID-姓名-手机号-团队成员分组-类型
async function teamUserExport() {
  const title = [
    "团队成员ID",
    "成员姓名",
    "手机号",
    "团队成员分组",
    "类型",
    "学校",
    "年级",
    "班级",
  ];
  if (like.value) {
  }
  // 获取团队成员
  let cond = {
    teamid: ID.value,
    _limit: 99999,
    _offset: offset.value,
    _like: like.value ? ["username", like.value] : undefined,
  };
  let groupId =
    teamusergroupid.value === "未分组" ? null : teamusergroupid.value;
  if (groupId !== "全部") {
    cond.teamusergroupid = groupId;
  }
  const { rows: data, count } = await asyncselectteamuser(cond);

  let ret = [
    title,
    ...data.map((e) => {
      return [
        e.userid,
        e?.user?.name,
        e?.user?.phonenum,
        formatGroupName(e?.teamusergroupid),
        admin[e?.isAdmin!],
        e?.user?.info?.school || "",
        e?.user?.info?.grade || "",
        e?.user?.info?.class || "",
      ];
    }),
  ];

  getExceltodownload(ret, `${p?.team?.name}-团队成员`);
}
</script>

<style scoped>
.container-box {
  padding: 0 20px;
}

.container-header {
  max-height: 100px;
}

.container-content {
  display: flex;
}

.form-item {
  padding: 30px 20px;
  display: flex;
  align-items: flex-start;
}

.form-item:hover {
  background: rgb(250, 250, 250);
  border-radius: 4px;
}

.form-item-check-box {
  flex: 0 0 auto;
  display: inline-block;
  width: 180px;
  line-height: 30px;
  font-size: 14px !important;
  font-weight: bold;
}

.desc {
  text-indent: 2rem;
  padding: 0 20px;
  line-height: 30px;
  font-size: 14px;
  color: #7f7f7f;
  /* max-height: 200px; */
  /* 隐藏超出容器的部分 */
  overflow: hidden;
  /* 必须结合webkit-box */
  display: -webkit-box;
  /* 设置flex方向为纵向 */
  -webkit-box-orient: vertical;
  /* 显示的行数 */
  white-space: normal;
  /* 使用省略号表示超出的文本 */
  text-overflow: ellipsis;
}

.desc:hover {
  background: rgb(250, 250, 250);
  border-radius: 4px;
}

.save-btn {
  margin: 0 20px;
}

.btn-box {
  line-height: 30px;
}

.container-right {
  min-width: 300px;
}

.catebag-list,
.container-right {
  height: calc(100vh - 300px);
}

.container-right-table {
  height: calc(100vh - 220px);
  transition: background-color 0.3s ease;
}

.catebag-box {
  display: flex;
  flex-wrap: wrap;
}

.catebag-intable-label {
  margin: 4px;
  padding: 0 10px;
  box-sizing: border-box;
  border-radius: 3px;
  height: 30px;
}

.pager {
  margin-top: 10px;
  margin-right: 0;
  float: right;
}
</style>

<style>
#courseCfg .catebag-cfg-container {
  height: auto;
  /* overflow: hidden; */
}
</style>
